package com.controller;

import com.beans.DeviceEntity;
import com.beans.ErrorStatusEnum;
import com.beans.FileDepotEntity;
import com.beans.RadioDepotEntity;
import com.common.entity.R;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author wyj
 */
@Transactional(rollbackFor = Exception.class)
@RestController
@RequestMapping("fileDepot")
public class FileDepotController {

    @PersistenceContext
    private EntityManager entityManager;

    @PostMapping("mergeFileDepot")
    public R mergeFileDepot(HttpServletRequest request,FileDepotEntity fileDepotEntity, MultipartFile fileZipTem) throws IOException {
        fileDepotEntity.setCreateTime(new Date());
        fileDepotEntity.setState(1);
        fileDepotEntity.setFileName(fileZipTem.getOriginalFilename());
        fileDepotEntity.setFileSize(fileZipTem.getSize()+"");
        fileDepotEntity.setFileZip(fileZipTem.getBytes());
        fileDepotEntity.setAuthor(request.getSession().getAttribute("username")+"");

        entityManager.merge(fileDepotEntity);

        return R.ok();
    }

    /**
     * 分页获取行业资讯
     *
     * @param page  第几页
     * @param rows  每页几条数据
     * @param sort  排序字段名
     * @param order 排序方式  asc desc
     * @return com.common.entity.R
     * @author gm
     * @date 2020/6/2
     */
    @GetMapping("fileDepotPage")
    public R fileDepotPage(Integer state, Integer page, Integer rows, String sort, String order) {
        //region 组装hql
        StringBuilder sql = new StringBuilder("select id, author, DATE_FORMAT(createTime,'%Y-%m-%d %H:%i:%s') as createTime, summary, fileName, fileSize, state, titleType from file_depot where 1 = 1 ");
        StringBuilder countSql = new StringBuilder("select count(id) from file_depot where 1 = 1 ");

        if (state != null) {
            sql.append(" and state = :state ");
            countSql.append(" and state = :state ");
        }
        if (!StringUtils.isEmpty(sort)) {
            sql.append(" order by ").append(sort).append(" ");
            if (!StringUtils.isEmpty(order)) {
                sql.append(order);
            }
        }
        if (page != null && rows != null) {
            sql.append(" limit :offset , :rows ");
        }
        //endregion 组装hql
        //region 组装查询对象和参数
        Query query = entityManager.createNativeQuery(sql.toString()).unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        Query queryCount = entityManager.createNativeQuery(countSql.toString());

        if (state != null) {
            query.setParameter("state", state);
            queryCount.setParameter("state", state);
        }
        if (page != null && rows != null) {
            query.setParameter("offset", (page - 1) * rows).setParameter("rows", rows);
        }
        List resultList = query.getResultList();
        /**
         * resultList.stream().forEach(a->a.setFileZip(null));
         */
        Object count = queryCount.getSingleResult();
        R ok = R.ok();
        ok.put("total", count);
        ok.put("rows", resultList);
        return ok;
    }

    /**
     * 删除行业资讯
     *
     * @param id
     * @return com.common.entity.R
     * @author gm
     * @date 2020/6/2
     */
    @PostMapping("deleteFileDepot")
    public R deleteFileDepot(Integer id) {
        if (id == null) {
            return R.error(ErrorStatusEnum.PARAMS_CANNOT_BE_NULL_ERROR.code(), "停用操作，id不能为空!");
        }
        entityManager.createNativeQuery("update file_depot set state = 0 where id = :id").setParameter("id", id).executeUpdate();
        return R.ok();
    }

    @GetMapping("/download")
    public void downLoad(HttpServletResponse response,String fileName,Integer id) {
        /** 将文件名称进行编码 */
        try {
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            response.setContentType("content-type:octet-stream");

            List<FileDepotEntity> list = entityManager.createNativeQuery("select * from file_depot where id = :id",FileDepotEntity.class).setParameter("id", id).getResultList();
            if(list.size() > 0) {
                /** 将流中内容写出去 */
                OutputStream outputStream = response.getOutputStream();
                outputStream.write(list.get(0).getFileZip());
                outputStream.close();
            }

        } catch (Exception e) { e.printStackTrace();}
    }

    @GetMapping("/downloadALL")
    public void downloadALL(HttpServletResponse response) {
        /** 将文件名称进行编码 */
        try {
            String TimeNow = new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime());
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("wps"+TimeNow+".zip", "UTF-8"));
            response.setContentType("content-type:octet-stream");

            List<FileDepotEntity> list = entityManager.createNativeQuery("select * from file_depot where state = 1",FileDepotEntity.class).getResultList();
            list.stream().forEach(l->l.setFileName(l.getId()+".zip"));

            Map<String,byte[]> map = getRadioAndFile();
            for (Map.Entry<String, byte[]> m : map.entrySet()) {
                FileDepotEntity f = new FileDepotEntity();
                f.setFileName(m.getKey());
                f.setFileZip(m.getValue());
                list.add(f);
            }

            if(list.size() > 0) {
                /** 将流中内容写出去 */
                OutputStream outputStream = response.getOutputStream();
                XmlDo4j.toZip2(list, outputStream);
                outputStream.close();
            }
        } catch (Exception e) { e.printStackTrace();}
    }

    /**
     * 得到单选题和操作题的xml文件
     * @return
     */
    public Map<String,byte[]> getRadioAndFile() {
        Map<String,byte[]> map = new HashMap<>();
        List<RadioDepotEntity> radioList = entityManager.createNativeQuery("select * from radio_depot where  state = 1 ",RadioDepotEntity.class).getResultList();
        if (radioList.size() > 0) {
            byte[] bytes = new XmlDo4j().createRadioDocument(radioList);
            map.put("outputRadio.xml",bytes);
        }

        List<FileDepotEntity> fileList = entityManager.createNativeQuery("select * from file_depot where  state = 1 ",FileDepotEntity.class).getResultList();
        if (fileList.size() > 0) {
            byte[] bytes = new XmlDo4j().createFileDocument(fileList);
            map.put("outputFile.xml",bytes);
        }

        List<DeviceEntity> studentList = entityManager.createNativeQuery("select * from device",DeviceEntity.class).getResultList();
        if (studentList.size() > 0) {
            byte[] bytes = new XmlDo4j().createStudentDocument(studentList);
            map.put("testees.xml",bytes);
        }

        return map;
    }

}
